package com.example.auth.controller;

import com.example.auth.entity.SysUser;
import com.example.auth.service.CaptchaService;
import com.example.auth.service.SmsService;
import com.example.common.dto.Result;
import com.example.common.security.JwtUtils;
import com.example.auth.dto.LoginDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * auth controller
 * will be used by user to login (login & generate token; captcha code and sms code)
 *
 * @author cui haida
 * @version JDK 8
 * 2025/8/4
 */
@RestController
@RequestMapping("/auth")
public class AuthController {

    /**
     * the utils of jwt
     */
    public JwtUtils jwtUtils;

    /**
     * the manager of authentication
     */
    @Resource
    private AuthenticationManager authenticationManager;

    /**
     * the service of sms
     * will send sms code to the phone
     */
    @Resource
    private SmsService smsService;

    /**
     * the service of captcha
     * will generate the captcha code
     */
    @Resource
    private CaptchaService captchaService;

    /**
     * login
     * 1. auth the user by query username and password in db
     * 2. build claim and gen token
     * 3. return token
     *
     * @param loginDTO login params
     * @return the token
     */
    @PostMapping("/login")
    public Result<Map<String, String>> login(@RequestBody LoginDTO loginDTO) {
        // do auth by username and password
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginDTO.getUsername(),
                        loginDTO.getPassword()
                )
        );

        // get the whole user info
        SysUser userDetails = (SysUser) authentication.getPrincipal();

        // gene token
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", userDetails.getId());
        claims.put("roles", userDetails.getAuthorities());

        String token = jwtUtils.generateToken(userDetails.getUsername(), claims);

        // return the token
        Map<String, String> result = new HashMap<>();
        result.put("token", token);
        return Result.success(result);
    }

    /**
     * get the captcha code
     * 1. generate the captcha code by captcha service (+ - * /)
     * 2. return the captcha code(key is uuid, value is captcha expression)
     *
     * @return the captcha code
     */
    @GetMapping("/captcha")
    public ResponseEntity<?> getCaptcha() {
        String key = UUID.randomUUID().toString();
        String expression = captchaService.generateCaptcha(key);
        Map<String, String> result = new HashMap<>();
        result.put("key", key);
        result.put("expression", expression);
        return ResponseEntity.ok(result);
    }

    /**
     * get the sms code
     * will send the sms code to the phone
     *
     * @param phone phone number
     */
    @PostMapping("/sms/code")
    public ResponseEntity<?> sendSmsCode(@RequestParam String phone) {
        smsService.sendSmsCode(phone);
        return ResponseEntity.ok().build();
    }
}